﻿/******************************************************************************
 * Name			: Packet.hpp
 * Author		: 671643387
 * Date			: 2015年9月13日
 * Description	:
 *****************************************************************************/

#ifndef COMMON_PACKET_PACKET_HPP_
#define COMMON_PACKET_PACKET_HPP_

#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include <dev/net/TcpConnectionInputStream.hpp>
#include <dev/net/TcpConnectionOutputStream.hpp>

namespace sxr
{
    namespace common
    {
        //// 数据包数据类型
        typedef uint16_t    packet_id_t;
        typedef uint16_t    packet_size_t;

        class Player;
        class Packet;
        typedef boost::shared_ptr<Packet> PacketPtr;

		/**
		 * @brief 数据包类，服务器处理的所有数据包从该类继承
		 */
        class Packet : public boost::noncopyable
        {
        public:
            struct _stHead
            {
                packet_id_t id;             // 包ID
                packet_size_t size;         // 包大小
            };

        protected:
            /**
             * @brief 数据包构造函数
             * @param id	包ID
             * @param size  包数据大小
             * @param buff  缓存
             */
            Packet(int id, size_t size, char* buff);
            virtual ~Packet(void);

        public:
            /**
             * @brief 判断能否从流中读取一个完整的包
             * @param is	网络输入流
             * @param head  包头数据
             * @return bool
             */
            static bool canReadPacket(dev::net::TcpConnectionInputStream& is, struct _stHead& head);

        public:
			/**
			 * @brief 从网络输入流读取数据包
			 * @param is	网络输入流
			 * @return bool
			 */
            bool read(dev::net::TcpConnectionInputStream& is);

			/**
			 * @brief 把数据包数据写入网络输出流
			 * @param os	网络输出流
			 */
			void write(dev::net::TcpConnectionOutputStream& os);

			/**
			 * @brief 数据包数据是否空（全部写到网络）
			 * @param os	网络输出流
			 */
			bool empty() { return (bytsWrote_ == size_); }

            /**
             * @brief 处理数据包
             * @param player    Player
             * @return 成功返回true
             */
            virtual bool execute(Player* player) = 0;

        protected:
            int id_;
			size_t size_;
            char* buffer_;

		private:
			size_t bytsWrote_;
        };
    }
}

#endif /* COMMON_PACKET_PACKET_HPP_ */
